package com.norma.spring.framework.beans.support;

import com.norma.spring.framework.beans.config.NormaBeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
 * @author zhangchaofeng
 * @date 2020/11/17
 * @description
 */
public class NormaBeanDefinitionReader {

    private Properties properties = new Properties();

    private List<String> registerBeanClasses = new ArrayList<>();

    /**
     * 包扫描路径
     */
    private final String SCAN_PACKAGE = "scanPackage";

    /**
     * 通过URL找到所对应的文件
     */
    public NormaBeanDefinitionReader(String... configLocation) {

        InputStream resourceAsStream = this.getClass().getClassLoader()
                .getResourceAsStream(configLocation[0].replace("classpath:", ""));
        try {
            properties.load(resourceAsStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (resourceAsStream != null) {
                try {
                    resourceAsStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        doScanner(properties.getProperty(SCAN_PACKAGE));

    }

    /**
     * 扫描
     */
    private void doScanner(String scanPackage) {
        URL resource = this.getClass().getClassLoader()
                .getResource("/" + scanPackage.replaceAll("\\.", "/"));
        File file = new File(resource.getFile());
        for (File listFile : file.listFiles()) {
            if (listFile.isFile()) {
                if (listFile.getName().endsWith(".class")) {
                    String className = scanPackage + "." + listFile.getName()
                            .replaceAll(".class", "");
                    registerBeanClasses.add(className);
                }
            } else {
                //dictionary
                doScanner(scanPackage + "." + listFile.getName());
            }
        }
    }

    public Properties getProperties() {
        return this.properties;
    }

    /**把配置文件中扫描到的所有配置信息转换成NormaBeanDefinition,方便之后IOC*/
    public List<NormaBeanDefinition> loadBeanDefinitions() {
        List<NormaBeanDefinition> result = new ArrayList<>();
        for (String registerBeanClass : registerBeanClasses) {
            NormaBeanDefinition beanDefinition = doCreateBeanDefinition(registerBeanClass);
            if (beanDefinition == null) {
                continue;
            }
            result.add(beanDefinition);
        }
        return result;
    }

    private NormaBeanDefinition doCreateBeanDefinition(String className) {
        try {
            Class<?> bean = Class.forName(className);
            if (!bean.isInterface()) {
                NormaBeanDefinition beanDefinition = new NormaBeanDefinition();
                beanDefinition.setBeanClassName(className);
                beanDefinition.setFactoryBeanName(toLowerFirstCase(bean.getSimpleName()));
                return beanDefinition;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String toLowerFirstCase(String simpleName) {
        //大小写字母的ASCII相差32 大写字母的ASCII小于小写字母
        //在char中做算学运算，其实就是对ASCII做算学运算
        char[] chars = simpleName.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }

}
